package net.pulseproject.router.systemtest;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;

import javax.sound.midi.MidiMessage;
import javax.sound.midi.Receiver;
import javax.sound.midi.ShortMessage;

import net.pulseproject.commons.midi.MessageAnalyzer;
import net.pulseproject.commons.midi.entity.MidiSocket;
import net.pulseproject.commons.util.MidiUtil;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class MidiReceiverCollector implements Receiver {

	private static final Log LOG = LogFactory.getLog(MidiReceiverCollector.class);
	
	private final Collection<ShortMessage> filteredMessages = new LinkedList<ShortMessage>();
	
	private final Collection<ShortMessage> unfilteredMessages = new LinkedList<ShortMessage>();
	
	private final MidiSocket socketFilter;
	
	private final MessageAnalyzer analyzer;
	
	
	public MidiReceiverCollector(final MidiSocket socketFilter, final MessageAnalyzer analyzer) {
		LOG.debug("new MidiReceiverCollector(socketFilter=" + socketFilter + ", analyzer)");
		this.socketFilter = socketFilter;
		this.analyzer = analyzer;
	}

	@Override
	public final void send(final MidiMessage realMessage, final long timeStamp) {
		final ShortMessage message = (ShortMessage) realMessage;
		LOG.info("send(message=" + MidiUtil.toString(message) + ", timeStamp)");
		
		final MidiSocket messageSocket = this.analyzer.createMidiSocket(message, this.socketFilter.getPort());
		final Collection<ShortMessage> messages;
		
		if(messageSocket.equals(this.socketFilter) == true) {
			LOG.trace(" ... adding as filtered.");
			messages = this.filteredMessages;
		} else {
			LOG.trace(" ... adding as unfiltered.");
			messages = this.unfilteredMessages;
		}
		
		messages.add(message);
	}

	@Override
	public final void close() {
		LOG.info("close()");
	}
	
	public final Collection<ShortMessage> getFilteredMessages() {
		return Collections.unmodifiableCollection(this.filteredMessages);
	}
	
	public final Collection<ShortMessage> getUnfilteredMessages() {
		return Collections.unmodifiableCollection(this.unfilteredMessages);
	}
	
	public final MidiSocket getSocket() {
		return this.socketFilter;
	}
	
	@Override
	public final String toString() {
		return "ReceiverCollector[filteredMessages=" + this.filteredMessages.size() + ", " +
				"unfilteredMessages=" + this.unfilteredMessages.size() + "]";
	}
}
